package com.langshixiaobai.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.langshixiaobai.eneity.User;
import com.langshixiaobai.game.Matcher;
import com.langshixiaobai.game.MessageRequest;
import com.langshixiaobai.game.MessageResponse;
import com.langshixiaobai.game.OnlineUserMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.net.InetAddress;

//连接匹配
@Component
public class MatchApi extends TextWebSocketHandler {

    @Autowired
    private OnlineUserMap onlineUserMap;

    //用于转换/解析JSON数据
    private ObjectMapper objectMapper = new ObjectMapper();


    @Autowired
    private Matcher matcher;

    //进入大厅之后
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        try {
            //由于之前将HttpSession存入到WebSocketSession中
            //所以可以通过WebSocketSession中拿去数据
            User user = (User) session.getAttributes().get("user");
            //防止同一用户多开，通过检验用户是否在hashmap中存在来进行检验 
            if (onlineUserMap.getFromGameHall(user.getUserId()) != null ||
                onlineUserMap.getFromGameRoom(user.getUserId()) != null
            ) {
                //检测到多开
                MessageResponse messageResponse = new MessageResponse();
                //检测到多开时，阻止当前会话进入大厅
                messageResponse.setOK(true);
                messageResponse.setReason("禁止多开");
                messageResponse.setMessage("repeatLogin");
                //发送给前端，禁止多开
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageResponse)));
                //主动断开连接，关掉多开的连接会话,直接关闭太激进，交给前端处理，页面跳转后，连接就会断开
                //session.close();
                return;
            }else{
                onlineUserMap.enterGameHall(user.getUserId(), session);
                System.out.println("玩家：" + user.getUserId() + ": " + user.getUsername() + " 进入大厅");
            }
        } catch (NullPointerException e) {
            //抛出异常，代表当前会话没有用户信息，需要重新登入
            MessageResponse messageResponse = new MessageResponse();
            messageResponse.setOK(false);
            messageResponse.setReason("尚未登入，不能进入后续匹配");
            //返回给前端错误信息
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageResponse)));
        }

    }

   @Override
   protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
       String payload = message.getPayload();

       User user = (User)session.getAttributes().get("user");
       //用来响应给前端
       MessageResponse messageResponse = new MessageResponse();
       //将前端传过来的JSON数据，通过ObjectMapper转换成对应的信息
       //MessageRequest用于存储前端发送的匹配请求信息
       MessageRequest messageRequest = objectMapper.readValue(payload, MessageRequest.class);
       //
       String requestMessage = messageRequest.getMessage();
       if (requestMessage.equals("startMatch")){
           //开始匹配，返回startMatch信息
          messageResponse.setOK(true);
          messageResponse.setMessage("startMatch");
          matcher.addUser(user);

       }else if(requestMessage.equals("stopMatch")){
           //如果停止匹配，则返回对应stopMatch信息
           messageResponse.setOK(true);
           messageResponse.setMessage("stopMatch");
           matcher.removeUser(user);
       }else{
           //非法匹配请求
           messageResponse.setOK(false);
           messageResponse.setMessage("非法匹配请求");
       }
       session.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageResponse)));

    }

  //关闭之后
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            User user = (User) session.getAttributes().get("user");
            //获取相同userId的连接会话
            //由于上述调用session.close()同样也会走这个方法
            //所以要进行判定
            WebSocketSession webSocketSession = onlineUserMap.getFromGameHall(user.getUserId());
            // 只有相等时候，才能从HashMap中除去这个userId
            //否则就会因为用户多开，session不同，但是userId相同
            //导致误删除相同的userId的不同会话
            if(webSocketSession == session){
                onlineUserMap.removeGameHall(user.getUserId());
                System.out.println("用户离开匹配 ");
            }
            matcher.removeUser(user);
        } catch (NullPointerException e) {
            //可能用户不再HashMap中，会抛出空指针异常，与上述处理操作相同
            MessageResponse messageResponse = new MessageResponse();
            messageResponse.setOK(false);
            messageResponse.setReason("尚未登入，请重新登入");
            //返回给前端错误信息,TextMessage是WebSocket用来传输文本信息的类
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageResponse)));
        }

    }
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            User user = (User) session.getAttributes().get("user");
            //获取相同userId的连接会话
            //由于上述调用session.close()同样也会走这个方法
            //所以要进行判定
            WebSocketSession webSocketSession = onlineUserMap.getFromGameHall(user.getUserId());
            // 只有相等时候，才能从HashMap中除去这个userId
            //否则就会因为用户多开，session不同，但是userId相同
            //导致误删除相同的userId的不同会话
            if(webSocketSession == session){
                onlineUserMap.removeGameHall(user.getUserId());
                System.out.println("用户离开匹配 ");
            }
            matcher.removeUser(user);
        } catch (NullPointerException e) {
            //可能用户不再HashMap中，会抛出空指针异常，与上述处理操作相同
            MessageResponse messageResponse = new MessageResponse();
            messageResponse.setOK(false);
            messageResponse.setReason("尚未登入，请重新登入");
            //返回给前端错误信息,TextMessage是WebSocket用来传输文本信息的类
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageResponse)));
        }
    }



}
